package com.kungfu.controller;

import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import com.kungfu.config.Constant;
import com.kungfu.entity.*;
import com.kungfu.entity.request.BaseDataEntity;
import com.kungfu.entity.request.BaseRequest;
import com.kungfu.entity.request.FlagChangeRequest;
import com.kungfu.entity.request.MxRequest;
import com.kungfu.entity.response.*;
import com.kungfu.service.MxService;
import com.kungfu.service.ZzdService;
import com.kungfu.utils.DateUtils;
import com.kungfu.utils.HttpUtils;
import com.kungfu.utils.ResultCodeEnum;
import com.kungfu.utils.XmlConvertEntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
public class DataController extends BaseController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ZzdService zzdService;

    @Autowired
    private MxService mxService;

    @Autowired
    private HttpUtils httpUtils;

    @Autowired
    private DateUtils dateUtils;

    @PostMapping("/uploadData")
    public ResponseEntity<String> uploadData(@RequestBody String data) {
        String methodName = "uploadData";
        printDebug(methodName, data);
        UploadDataResponse response = new UploadDataResponse();
        MxRequest request = null;
        try {
            request = new Gson().fromJson(data, MxRequest.class);
            if (StringUtils.isEmpty(request.getSFZH()) || StringUtils.isEmpty(request.getZYH()) || request.getRESULTSET().size() == 0) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return ResponseEntity.ok(response.toString());
            }
            //查询转诊单信息
            GfjsZzd zzd = zzdService.queryInfoByZYH(request.getZYH());
            if (zzd == null) {
                response.setResult(ResultCodeEnum.ZYH_NOT_EXIST);
                printDebug(methodName, response.toString());
                return ResponseEntity.ok(response.toString());
            }
            //插入收据单汇总信息
            ReceiptRolls receiptRolls = new ReceiptRolls();

            Date date = dateUtils.parseSJDH2Datetime(request.getRESULTSET().get(0).getSJDH());
            receiptRolls.setReceiptNo(zzd.getZzdNo() + dateUtils.createSJDH(date));
            receiptRolls.setUserName(zzd.getUserName());
            receiptRolls.setCardNo(zzd.getCardNo());
            receiptRolls.setCardId(zzd.getJzCardNo());
            receiptRolls.setReceiptCreateTime(dateUtils.parseSJDH2Datetime(request.getRESULTSET().get(0).getSJDH()));
            receiptRolls.setIntoTime(new Date());
            receiptRolls.setZzdNo(zzd.getZzdNo());
            receiptRolls.setIntoHospitalId(zzd.getReceiveHospitalId());
            receiptRolls.setAdmissionNumber(zzd.getRegisterNo());
            receiptRolls.setReceiptType(zzd.getZzdType());
            receiptRolls.setStartDate(dateUtils.parseSJDH2Datetime(request.getRESULTSET().get(0).getSJDH()));
            receiptRolls.setEndDate(dateUtils.parseSJDH2Datetime(request.getRESULTSET().get(0).getSJDH()));
            receiptRolls.setDateNum(Integer.valueOf(1));
            receiptRolls.setOutHospitalId(zzd.getCreateHospitalId());
            receiptRolls.setStatus(0);
            zzdService.insertRolls(receiptRolls);
            //排除规则外项目
            DataInsertResult insertResult = zzdService.syncMxItem(request.getRESULTSET().get(0).getSJDH(), zzd.getZzdNo(), request.getRESULTSET());
            switch (insertResult.getResultCode()) {
                case Constant.CHECK_DATA_RESULT.CHECK_NOT_OK:
                    response.setResult(ResultCodeEnum.CHECK_NOT_OK);
                    printDebug(methodName, response.toString());
                    return ResponseEntity.ok(response.toString());
                case Constant.CHECK_DATA_RESULT.DATA_NOT_EXIST:
                    response.setResult(ResultCodeEnum.DATA_NOT_EXIST);
                    response.setNotExistData(zzdService.queryUserUnExistData(request.getRESULTSET().get(0).getHZID()));
                    printDebug(methodName, response.toString());
                    return ResponseEntity.ok(response.toString());
            }
            //通知数据同步

            response.setResult(ResultCodeEnum.SUCCESS);
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/queryJsData")
    public ResponseEntity<String> queryJsData() {
        BaseRequest request = null;
        String methodName = "queryJsData";
        printDebug(methodName, "");
        QueryDailyResponse response = new QueryDailyResponse();
        try {
            List<HzBean> list = zzdService.queryUnreadSum();
            response.setList(list);
            response.setResult(ResultCodeEnum.SUCCESS);
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }


    @PostMapping("/readFlagChange")
    public ResponseEntity<String> readFlagChange(@RequestBody String data) {
        BaseResponse response = new BaseResponse();
        String methodName = "readFlagChange";
        printDebug(methodName, data);
        FlagChangeRequest request = null;
        try {
            request = new Gson().fromJson(data, FlagChangeRequest.class);
            if (StringUtils.isEmpty(request.getHZRQ()) || StringUtils.isEmpty(request.getZZDH())) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return ResponseEntity.ok(response.toString());
            }
            int result = zzdService.changeReadFlag(request);
            if (result > 0) {
                response.setResult(ResultCodeEnum.SUCCESS);
            } else {
                response.setResult(ResultCodeEnum.DB_OPERATE_ERROR);
            }
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/checkRuleCount")
    public ResponseEntity<String> checkRuleCount() {
        String methodName = "checkRuleCount";
        printDebug(methodName, "");
        CountResponse response = new CountResponse();
        try {
            int localRuleCount = Constant.getMxMap().size();
            int noRuleCount = mxService.queryNoRuleCount();
            response.setResult(ResultCodeEnum.SUCCESS);
            response.setRuleCount((localRuleCount + noRuleCount) + "");
        } catch (JsonParseException ex) {
            printDebugException(methodName, ex);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception ex) {
            printDebugException(methodName, ex);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/queryNoExist")
    public ResponseEntity<String> queryNoExist(@RequestBody String data) {
        QueryNoResponse response = new QueryNoResponse();
        String methodName = "queryNoExist";
        printDebug(methodName, data);
        List<String> result = new ArrayList<>();
        try {
            List<String> list = new Gson().fromJson(data, new TypeToken<List<String>>() {
            }.getType());
            List<String> localDataNo = mxService.queryLocalNo();
            list.stream().filter(existItem -> !localDataNo.contains(existItem)).forEach(item -> result.add(item));
            response.setResult(ResultCodeEnum.SUCCESS);
            response.setData(result);
        } catch (JsonParseException ex) {
            printDebugException(methodName, ex);
            response.setResult(ResultCodeEnum.PARAM_ERROR);

        } catch (Exception ex) {
            printDebugException(methodName, ex);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/uploadBaseData")
    public ResponseEntity<String> uploadBaseData(@RequestBody String data) {
        BaseResponse response = new BaseResponse();
        String methodName = "uploadBaseData";
        printDebug(methodName, data);
        try {
            List<BaseDataEntity> request = new Gson().fromJson(data, new TypeToken<ArrayList<BaseDataEntity>>() {
            }.getType());
            if (request.size() == 0) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return ResponseEntity.ok(response.toString());
            }
            int result = mxService.uploadData(request);
            if (result > 0) {
                response.setResult(ResultCodeEnum.SUCCESS);
            } else {
                response.setResult(ResultCodeEnum.DB_OPERATE_ERROR);
            }
        } catch (JsonParseException ex) {
            printDebugException(methodName, ex);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception ex) {
            printDebugException(methodName, ex);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/queryYpcdCount")
    public ResponseEntity<String> queryLocalYpcdCount() {
        String methodName = "queryYpcdCount";
        printDebug(methodName, "");
        CountResponse response = new CountResponse();
        try {
            int count = mxService.queryYpcdCount();
            response.setRuleCount(count + "");
            response.setResult(ResultCodeEnum.SUCCESS);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/queryYpcdNoExist")
    public ResponseEntity<String> queryYpcdNoExist(@RequestBody String data) {
        String methodName = "queryYpcdNoExist";
        QueryNoResponse response = new QueryNoResponse();
        printDebug(methodName, data);
        List<String> result = new ArrayList<>();
        try {
            List<String> list = new Gson().fromJson(data, new TypeToken<ArrayList<String>>() {
            }.getType());
            List<String> localData = mxService.queryYpcdNo();
            list.stream().filter(existItem -> !localData.contains(existItem)).forEach(item -> result.add(item));
            response.setResult(ResultCodeEnum.SUCCESS);
            response.setData(result);
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/updateYpcds")
    public ResponseEntity<String> updateYpcds(@RequestBody String data) {
        String methodName = "updateYpcds";
        BaseResponse response = new BaseResponse();
        printDebug(methodName, data);
        try {
            List<YpcdEntity> list = new Gson().fromJson(data, new TypeToken<ArrayList<YpcdEntity>>() {
            }.getType());
            if (list.size() == 0) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return ResponseEntity.ok(response.toString());
            }
            int result = mxService.uploadYpcds(list);
            if (result > 0) {
                response.setResult(ResultCodeEnum.SUCCESS);
            } else {
                response.setResult(ResultCodeEnum.DB_OPERATE_ERROR);
            }
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/queryUserDataToUpload")
    public ResponseEntity<String> queryUserDataToUpload() {
        UserDataResponse response = new UserDataResponse();
        String methodName = "queryUserDataToUpload";
        printDebug(methodName, "");
        try {
            List<String> list = mxService.queryNeedUploadUser();
            response.setUsers(list);
            response.setResult(ResultCodeEnum.SUCCESS);
        } catch (JsonParseException e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.PARAM_ERROR);
        } catch (Exception e) {
            printDebugException(methodName, e);
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/updateUserFlag")
    public ResponseEntity<String> updateUserFlag(@RequestBody String zyh) {
        BaseResponse response = new BaseResponse();
        String methodName = "updateUserFlag";
        printDebug(methodName, zyh);
        try {
            if (StringUtils.isEmpty(zyh)) {
                response.setResult(ResultCodeEnum.PARAM_ERROR);
                printDebug(methodName, response.toString());
                return ResponseEntity.ok(response.toString());
            }
            mxService.updateUserFlag(zyh);
            response.setResult(ResultCodeEnum.SUCCESS);
        } catch (JsonParseException e) {
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
            printDebugException(methodName, e);
        } catch (Exception e) {
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
            printDebugException(methodName, e);
        }
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }


    @PostMapping("/getChargeList")
    public ResponseEntity<String> queryChargeList() {
        String methodName = "getChargeList";
        printDebug(methodName, "");
        ChargeListResponse response = new ChargeListResponse();
        List<CYJXInfoEntity> list = zzdService.queryChargeList();
        response.setChargeList(list);
        printDebug(methodName, response.toString());
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/startSync")
    public ResponseEntity<String> startSync() {
        String methodName = "startSync";
        printDebug(methodName, "");
        int count = zzdService.queryItemCount();
        if (count > 0) {
            String s = httpUtils.getSyncStart(restTemplate, Constant.HospitalType.XH, Constant.HospitalType.HK);
            printDebug(methodName, "sync:statt:" + "result:" + s);
        }
        BaseResponse response = new BaseResponse();
        response.setResult(ResultCodeEnum.SUCCESS);
        return ResponseEntity.ok(response.toString());
    }

    @PostMapping("/syncSummary")
    public ResponseEntity<String> syncSummary(@RequestBody String data) {
        String methodName = "syncSummary";
        printDebug(methodName, data);
        BaseResponse response = new BaseResponse();
        try {
            CyxjInfoEntity entity = new Gson().fromJson(data, CyxjInfoEntity.class);
            entity.setInfo(XmlConvertEntityUtils.readStringXml(entity.getInfo()));
            int result = mxService.insertCyxj(entity);
            if (result >= 0) {
                response.setResult(ResultCodeEnum.SUCCESS);
            }
            printDebug(methodName, entity.toString());
        } catch (JsonParseException e) {
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
            printDebugException(methodName, e);
        } catch (Exception e) {
            response.setResult(ResultCodeEnum.SERVER_INTERNAL_ERROR);
            printDebugException(methodName, e);
        }
        return ResponseEntity.ok(response.toString());
    }
}
